package ua.kiev.tosik.price.gui;

import org.apache.log4j.Logger;
import org.jdesktop.swingx.JXStatusBar;
import org.jdesktop.swingx.plaf.basic.BasicStatusBarUI;
import ua.kiev.tosik.price.Main;
import ua.kiev.tosik.price.conf.Language;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class StatusBar implements PropertyChangeListener {

	private static StatusBar ourInstance;
	private static Logger logger = Logger.getLogger(StatusBar.class);
	private JXStatusBar statusBar;
	private JLabel imageLabel;
	private JLabel statusLabel;
	private JLabel memLabel;
	private String memText = "Mem: ";
	private NumberFormat formatter;
	private ImageIcon defaultIcon;
	private ImageIcon memIcon;
	private String defaultStatusText = "Done";
	private JXStatusBar.Constraint c1;
	private ImageIcon waitIcon;

	private JProgressBar progressBar;

	public static StatusBar getInstance() {
		if (ourInstance == null) {
			ourInstance = new StatusBar();
		}
		return ourInstance;
	}

	private StatusBar() {
		logger.debug("Initialize status bar");
		initComponents();
		updateLocale();
		statusBar.putClientProperty(BasicStatusBarUI.AUTO_ADD_SEPARATOR, true);
		c1.setFixedWidth(20);
		statusBar.add(imageLabel, c1);
		statusBar.add(statusLabel, JXStatusBar.Constraint.ResizeBehavior.FILL);

		progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
		progressBar.setPreferredSize( new Dimension(200, 16) );
		progressBar.setValue(0);
		progressBar.setStringPainted(true);
		progressBar.setVisible(false);
		statusBar.add(progressBar);

		memLabel.setText(getMemText());
		memLabel.setIcon(memIcon);
		memLabel.setToolTipText("Run Garbage Collector");
		memLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		memLabel.addMouseListener( new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				logger.debug("Run garbage collector");
				Main.gc();
			}
		});
		statusBar.add(memLabel, new JXStatusBar.Constraint(120));
		reset();
		Timer tm = new Timer(3000, new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				setMemText(Main.getUsedMemory());
			}
		});
		tm.start();
	}

	private void initComponents() {
		formatter = new DecimalFormat("#,###");
		statusBar = new JXStatusBar();
		imageLabel = new JLabel();
		statusLabel = new JLabel();
		memLabel = new JLabel();
		c1 = new JXStatusBar.Constraint();
	}

	public JXStatusBar getStatusBar() {
		return statusBar;
	}

	public String getMemText() {
		return memText;
	}

	public void setMemText(long mem) {
		this.memText = String.valueOf(mem);
		memLabel.setText("Mem: " + formatter.format(mem/1024) + " kb");
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if ( evt.getPropertyName().equals("ParseStart") || evt.getPropertyName().equals("SEARCH_START") || evt.getPropertyName().equals("COMPRESS_START") ) {
			setWait((String)evt.getNewValue());
		}
		if ( evt.getPropertyName().equals("FILE_DELETE_ALL_START") ) {
			setDeleteWait();
		}
		if ( evt.getPropertyName().equals("COMPRESS_START") ) {
			showProgress(true);
		}
		if ( evt.getPropertyName().equals("FILE_DELETE_ALL_OK") || evt.getPropertyName().equals("FILE_DELETE_ALL_DONE") || evt.getPropertyName().equals("ParseDone") || evt.getPropertyName().equals("SEARCH_DONE") || evt.getPropertyName().equals("COMPRESS_DONE") ) {
			reset();
		}
		if ( evt.getPropertyName().equals("COMPRESS_COUNT") ) {
			setProgressValue((Integer)evt.getNewValue());
		}
	}

	public void setStatusLabel(String statusText) {
		this.statusLabel.setText(statusText);
	}
	public synchronized void setImageLabel(ImageIcon image) {
		this.imageLabel.setIcon(image);
	}

	public void setStatus(String statusText, ImageIcon image) {
		setStatusLabel(statusText);
		setImageLabel(image);
	}

	public void setWait(String text) {
		setImageLabel(waitIcon);
		setStatusLabel(text);
	}

	public void setDeleteWait() {
		setImageLabel(waitIcon);
		setStatusLabel(Language.getInstance().get("app.statusbar.deleting.text"));
	}

	public void setProgressMax(int value) {
		progressBar.setMaximum(value);
	}

	public int getProgressValue() {
		return progressBar.getValue();
	}

	public void setProgressValue(int value) {
		progressBar.setValue(value);
	}

	public void setProgressString(String text) {
		progressBar.setString(text);
	}

	public void showProgress(boolean show) {
		if ( show != progressBar.isVisible() ) {
			progressBar.setVisible(show);
		}
	}

	public void updateLocale() {
		defaultIcon = new ImageIcon(Language.getInstance().get("app.statusbar.statusIcon"));
		memIcon = new ImageIcon(Language.getInstance().get("app.statusbar.memIcon"));
		waitIcon = new ImageIcon(Language.getInstance().get("app.wait.icon"));
		defaultStatusText = Language.getInstance().get("app.statusbar.statusText");
	}

	public void reset() {
		statusLabel.setText(defaultStatusText);
		imageLabel.setIcon(defaultIcon);
		memLabel.setIcon(memIcon);
		progressBar.setVisible(false);
		progressBar.setValue(0);
	}

}